package scene;

import game.Consts;

import java.util.ArrayList;

import raytracer.IntersectionResult;
import raytracer.Ray;

/// A class representing a simple 3D scene consisting of lights, triangle meshes and spheres.
public class Scene {
	// / Create an empty scene.
	public Scene() {
		camera = new Camera();
		shapes = new ArrayList<Shape>();
		pointLights = new ArrayList<PointLight>();
		spotLights = new ArrayList<SpotLight>();
		directionalLights = new ArrayList<DirectionalLight>();
		renderInfo = new RenderInfo();
		ambient = new AmbientLight(new Color(1f,1f,1f));
	}
	
	public IntersectionResult intersect(Ray ray) {
		return intersect(ray, 0);
	}
	
	public IntersectionResult intersect(Ray ray, float dieFastOnDistSquared) {
		IntersectionResult result = null;

		float shortestDistSquared = Float.MAX_VALUE;

		for (Shape sph : this.shapes) {
			
			IntersectionResult intersect = sph.intersect(ray);
			
			if (intersect != null && intersect.distSquared < shortestDistSquared && intersect.dist != Float.MAX_VALUE) {
				shortestDistSquared = intersect.distSquared;
				result = intersect;
				
				if(intersect.dist > 0 && intersect.distSquared < dieFastOnDistSquared) {
					break;
				}
			}
		}

		return result;
	}

	@Override
	public String toString() {
		String r = "";

		r += "Cam: " + camera + "\n" + "Info: " + renderInfo + "\n";

		for (Shape s : this.shapes) {
			r += "Shape: " + s + "\n";
		}

		for (AbstractLight l : this.pointLights) {
			r += "PointLight: " + l + "\n";
		}

		for (AbstractLight l : this.spotLights) {
			r += "SpotLight: " + l + "\n";
		}

		for (AbstractLight l : this.directionalLights) {
			r += "DirectionalLight: " + l + "\n";
		}

		return r;
	}

	// / The camera of the scene.
	public Camera camera;

	// / Shapes (triangles, spheres)
	public ArrayList<Shape> shapes;

	// / The lights in the scene.
	public ArrayList<PointLight> pointLights;
	public ArrayList<SpotLight> spotLights;
	public ArrayList<DirectionalLight> directionalLights;

	public RenderInfo renderInfo;

	public AmbientLight ambient;

	public int maxDepth = Consts.GLOBAL_MAXDEPTH;

	public int lives = 3;
	public int targets = 0;

}
